#include <iostream>

using std::cout;
using std::endl;

class Base1{
public:
    virtual
        void a()
        {
            cout<<"virtual void Base1::a()"<<endl;
        }
    virtual
        void b()
        {
            cout<<"virtual void Base1::b()"<<endl;
        }
    virtual
        void c()
        {
            cout<<"virtual void Base1::c()"<<endl;
        }

    virtual
        ~Base1(){

        }
};

class Base2{
public:
    virtual
        void a()
        {
            cout<<"virtual void Base2::a()"<<endl;
        }
    virtual
        void b()
        {
            cout<<"virtual void Base2::b()"<<endl;
        }

    void c()
    {
        cout<<"void Base2::c()"<<endl;
    }

    void d()
    {
        cout<<"void Base2::d()"<<endl;
    }

    virtual 
        ~Base2(){

        }
};

class Derived
: public Base1,
  public Base2
{
public:
    virtual
        void a(){
            cout<<"virtual Derived::a()"<<endl;
        }

    void c()    //这个c，继承自Base1（虚）和Base2（非虚），是虚函数
                //当来自Base1时，不需要显式写出virtual
    {
        cout<<"void Derived::c()"<<endl;
    }

    void d()
    {
        cout<<"void Derived::d()"<<endl;
    }
};

class Derived2
: public Derived
{
public:
    void c(){
        cout<<"c是虚函数，因为打印了Derived2的c"<<endl;
    }
};

void test(){
    Derived derived;
    printf("%p\n",&derived);

    cout<<endl;
    Base1 *pbase1= &derived;
    printf("%p\n",pbase1);
    pbase1->a();    //Derived a()
    pbase1->b();    //Base1 b()
    pbase1->c();    //Derived c()
    //为什么这里是Derived的c，而pbase2里调用的是Base2里的c？
    //在Base1的范围内寻找c，发现c被重写，连接到了新的c，即derived自己的c
    //而pbase2里的c只能看见自己的c，所以还是Base2的c
    //
    //这里有个问题，如果此时先调用没被重写的函数（无论是不是虚函数），
    //这个函数里面有被重写的函数
    //则里面调用的函数是重写的函数，而不是A自己的函数
    //参考question1.cc

    cout<<endl;
    Base2 *pbase2= &derived;
    printf("%p\n",pbase2);  //其他三个地址一样，pbase2是第二个虚函数指针，往下了一个单位
    pbase2->a();    //Derived a()
    pbase2->b();    //Base2 b()
    pbase2->c();    //Base2 c()
    pbase2->d();    //Base2 d()
    //在Base2的范围里找，找到c、d都没有被重写，所以仍然是base2的c、d

    cout<<endl;
    Derived *pderived=&derived;
    printf("%p\n",pderived);
    pderived->a();      //Derived a()
    //pderived->b();    Base1和Base2都有 b()，二义性
    pderived->Base1::b();   //Base1 b()
    pderived->Base2::b();   //Base2 b()
    pderived->c();          //Derived c()
    pderived->d();          //Derived d()

    cout<<endl;
    Derived2 derived2;
    Derived *pd=&derived2;
    pd->c();
    //如果这里调用的是Derived的c，则说明c不是虚函数，和16day的11结果一致
    //如果是Derived2的c，说明是虚函数，实现了动态多态
    //结果显示c是虚函数
    
    delete pderived;
    delete pd;
}

int main()
{   
    test();
    return 0;
}

